﻿#region All usings
using System;
using System.Linq;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
#endregion


namespace senSimulator.DrawableComponents.TrafficLights.Types
{
    class TrafficLightForCars : TrafficLight
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public TrafficLightForCars(Game game, Vector2 spawnPosition, Texture2D[] textureNames, Vector2[] textureCenters, int posX, int posY, int rotationInDegrees, string trafficLightID, int distanceToTrafficLight)
            : base(game, spawnPosition, textureNames, textureCenters, posX, posY, rotationInDegrees, trafficLightID, distanceToTrafficLight)
        {}


        /// <summary>
        /// Traffic light states for the Car light
        /// </summary>
        /// <param name="state">New state of the traffic light</param>
        public override void ChangeTrafficLightState(int state)
        {
            switch (state)
            {
                case 0:     // OFF
                    _trafficLightState = state;
                    _blinking = false;
                    SwitchOff();
                    break;
                case 1:     // GREEN
                case 2:     // ORANGE
                case 3:     // RED
                    _trafficLightState = state;
                    _blinking = false;
                    _errorAndOffstate = false;
                    break;
                case 7:     // ERROR STATE
                    _trafficLightState = state - 5;
                    _blinking = true;
                    _errorAndOffstate = true;
                    break;
                default:    // NOT SUPPORTED
                    Console.WriteLine("Car traffic light does not support state number: " + state);
                    break;
            }
        }


        /// <summary>
        /// Move a car based on the different states
        /// </summary>
        public override void MoveTraffic(Controller controller)
        {
            for (int i = 0; i < _trafficLightQueueLength; i++)
            {
                // Get the car and check if it has reached the end
                Traffic car;
                lock(_trafficLightQueue) {
                    car = _trafficLightQueue.ElementAt(i);
                }
                if (car.IsFinished())
                {
                    RemoveTraffic(car);
                    break;
                }

                // Check if the car hits the sensor
                if (car.GetCurrentWayPoint() == 1 && !car.SensorTriggered() && car.GetPosition() != car.GetFirstWayPoint())
                {
                    car.SetSensorTriggered(true);
                    controller.SendSensorTriggerToController(this.getName(), 1, car.GetTo());
                }

                // If the lights are green, off, error state or the sensor is triggered, move!
                if (_trafficLightState == 1 || car.SensorTriggered() || _errorAndOffstate)
                    car.Move();
                else if (car.GetCurrentWayPoint() == 0)
                {
                    if (i > 0)
                    {
                        Traffic previousCar;
                        lock (_trafficLightQueue)
                        {
                            previousCar = _trafficLightQueue.ElementAt(i - 1);
                        }
                        if (previousCar.SensorTriggered())
                            car.Move();
                        else if ((Math.Abs(car.GetPosition().X - previousCar.GetPosition().X) + Math.Abs(car.GetPosition().Y - previousCar.GetPosition().Y) > previousCar.GetLength()))
                        {
                            car.Move(previousCar.GetPosition(), previousCar.GetLength());
                        }
                        else
                            car.Stop();
                    }
                    else
                        car.Move();
                }
                else
                    car.Stop();
            }
        }
    }
}
